/**
 * 版权 (c) 2011 惠久久
 * 保留所有权利。
 */

package cn.lunatic.uplaod;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

/**
 * 描述：
 * 
 * @author guosl 创建时间：Feb 22, 2011
 */

public class UploadServlet extends HttpServlet {

	private static final long serialVersionUID = -5659995315515736376L;
	
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		String fileSavePath = getInitParameter("path");
		String result = "";
		boolean isSrcFileName = "true".equalsIgnoreCase(req.getParameter("isSrcFileName"))?true:false;
		if (org.apache.commons.lang.StringUtils.isBlank(fileSavePath)) {
			JSONObject obj = new JSONObject();
			obj.put("error", 1);
			obj.put("datas", "上传文件临时文件目录");
			result = obj.toString();
			System.out.println("上传文件临时文件目录不存在!");
			resp.setCharacterEncoding("utf-8");
			resp.getWriter().print(result);
			resp.getWriter().flush();
			return;
		}
		File temp = new File(fileSavePath);
		if (!temp.exists()) {
			temp.mkdirs();
		}
		// 保存文件到物理磁盘
		try {
			result = saveUploadFiles(req, fileSavePath, System.currentTimeMillis() + "",isSrcFileName);
		} catch (Exception e) {
			JSONObject obj = new JSONObject();
			obj.put("error", 1);
			obj.put("datas", "上传文件失败");
			result = obj.toString();
		}
		resp.setCharacterEncoding("utf-8");
		resp.getWriter().print(result);
		resp.getWriter().flush();
	}
	
	
	@SuppressWarnings("unchecked")
	public String saveUploadFiles(HttpServletRequest request, String basePath, String newFileName, boolean isSrcFileName)
			throws IOException {

		// 定义允许上传的文件扩展名
		String[] fileTypes = new String[] { "gif", "jpg", "jpeg", "png", "bmp",
				"txt", "xls", "zip", "rar" };
		// 最大文件大小
		long maxSize = 1 * 1024 * 1024;// 1MB
		String error = "";
		// 检查目录
		File uploadDir = new File(basePath);
		if (!uploadDir.exists()) {
			uploadDir.mkdirs();
		}
		// 检查目录写权限
		if (!uploadDir.canWrite()) {
			error = getError("上传目录没有写权限。");
			return error;
		}

		org.apache.commons.fileupload.FileItemFactory factory = new org.apache.commons.fileupload.disk.DiskFileItemFactory();
		org.apache.commons.fileupload.servlet.ServletFileUpload upload = new org.apache.commons.fileupload.servlet.ServletFileUpload(factory);
		upload.setHeaderEncoding("UTF-8");
		List items = null;
		try {
			items = upload.parseRequest(request);
		} catch (org.apache.commons.fileupload.FileUploadException e) {
			System.out.println("上传文件失败!" + e.getLocalizedMessage());
			error = getError("上传文件失败!");
			return error;
		}
		if (items == null) {
			error = getError("上传文件失败!");
			return error;
		}
		Iterator itr = items.iterator();
		while (itr.hasNext()) {
			org.apache.commons.fileupload.FileItem item = (org.apache.commons.fileupload.FileItem) itr.next();
			String fileName = item.getName();
			long fileSize = item.getSize();
			if (!item.isFormField()) {
				// 检查扩展名
				String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
				if (!Arrays.<String> asList(fileTypes).contains(fileExt)) {
					System.out.println("上传文件扩展名是不允许的扩展名");
					error = getError("上传文件扩展名是不允许的扩展名。");
					return error;
				}
				if ("zip".equals(fileExt)) {// 压缩包允许上传300M
					maxSize = 300 * 1024 * 1024;// 1MB
				}
				// 检查文件大小
				if (fileSize > maxSize) {
					System.out.println("上传文件大小超过限制");
					error = getError("上传文件大小超过限制。");
					return error;
				}
				if (isSrcFileName) {
					newFileName = fileName.substring(0, fileName
							.lastIndexOf("."));
				} else {
					if (org.apache.commons.lang.StringUtils.isBlank(newFileName)) {
						newFileName = System.currentTimeMillis() + "";
					}
				}
				newFileName = newFileName + "." + fileExt;
				try {
					File uploadedFile = new File(basePath, newFileName);
					item.write(uploadedFile);
				} catch (Exception e) {
					System.out.println("上传文件保存失败" + e.getLocalizedMessage());
					error = getError("上传文件保存失败。");
					return error;
				}

				// 上传成功
				JSONObject obj = new JSONObject();
				obj.put("error", 0);
				obj.put("datas", newFileName);
				error = obj.toString();
				return error;
			}

		}
		return error;
	}
	
	private String getError(String message) {
		JSONObject obj = new JSONObject();
		obj.put("error", 1);
		obj.put("datas", message);
		return obj.toString();
	}
}
